var MapObjectId=0;
var ToolTipId=0;
var MapLayerId=0;
var MapObjectIndex = new Object();
MapObjectIndex.LayerId = new Object();
MapObjectIndex.ObjectId = new Object();
	var DDM = new Object();
	DDM.im = new Image();
	DDM.im.src = 'images/dotblue_sm.gif';
			
var Layers = new function()
{
	
	var Layer = new Array();
	this.AddMapLayer = function(MLayer){
		Layer.push(MLayer);
	}
	this.MoveLayers =  function(){
		var start = new Date();
		for(var i=0; i<Layer.length; i++) {
			var ml = Layer[i];
			if (ml.Visible==true) {
				//ml.RemoveLayer();
				//ml.DrawLayer();
				ml.MoveLayer();
			} 
		}
		var end = new Date();
		//alert(end.getTime() + " start: " + start.getTime() + " diff: " + (end.getTime()-start.getTime())/1000 + " seconds");
	}
	this.RefreshLayers = function(){
		var start = new Date();
		for(var i=0; i<Layer.length; i++) {
			var ml = Layer[i];
			if (ml.Visible==true) {
				ml.RefreshLayer();
				
			} 
		}
		var end = new Date();
		//alert(end.getTime() + " start: " + start.getTime() + " diff: " + (end.getTime()-start.getTime())/1000 + " seconds");
	}
	this.RemoveLayers = function(){
		//jslog.info('Removing layers');
		for(var i=0; i<Layer.length; i++) {
			var ml = new MapLayer();
			ml = Layer[i];	
				ml.RemoveLayer();
		}
	}
	this.HideLayers = function(){
		//jslog.info('Removing layers');
		for(var i=0; i<Layer.length; i++) {
			var ml = new MapLayer();
			ml = Layer[i];	
				ml.HideLayer();
		}
	}
}
/**
 * @class Represents a collection of MapObject
 * This is considered a layer on a map
 */
function MapLayer()
{
	var LayerObjects = new Array();
	
	this.AddMapObject = function (MObject){
		//MapObjectIndex.LayerId[this.GetId()];
		if(MObject.SetLayerId){
			MObject.SetLayerId(this.GetId());
		}
		LayerObjects.push(MObject);	
	}
	this.RemoveMapObject = function (Index){
		LayerObject.splice(Index);
	}
	this.DrawLayer = function () {
		for(var i=0; i<LayerObjects.length; i++) {
			lo = LayerObjects[i];
			lo.LayerId = this.GetId();
			lo.DrawMe();
			//jslog.info("Drawing Layer");
			this.Visible = true;
		}
		
		MapObjectIndex.LayerId[this.GetId()]=this;
		Layers.AddMapLayer(this);
	}
	this.RefreshLayer = function(){
		for(var index=0; index<LayerObjects.length; index++) {
			var lo = LayerObjects[index];
			lo.Recalc();
			lo.RedrawMe();
		}
	}
	this.MoveLayer = function(){
		var vell = new VELatLong();
			vell.Latitude = this.CenterPoint.Lat;
			vell.Longitude = this.CenterPoint.Long;
			var p = map.LatLongToPixel(vell);
			var xmove = this.CenterPoint.x - p.x;
			var ymove = this.CenterPoint.y - p.y;
			this.CenterPoint.x -= xmove;
			this.CenterPoint.y -= ymove;

		for(var i=0; i<LayerObjects.length; i++) {
			lo = LayerObjects[i];
			//jslog.info(xmove + ' : ' + ymove);
			lo.MoveMe(xmove, ymove);
		}
	}
	this.ReDraw = function(){
		var vell = new VELatLong();
			vell.Latitude = this.CenterPoint.Lat;
			vell.Longitude = this.CenterPoint.Long;
			var p = map.LatLongToPixel(vell);
			var xmove = this.CenterPoint.x - p.x;
			var ymove = this.CenterPoint.y - p.y;
			this.CenterPoint.x -= xmove;
			this.CenterPoint.y -= ymove;
		for(var i=0; i<LayerObjects.length; i++) {
			lo = LayerObjects[i];
			lo.ReDrawMe(xmove, ymove);
		}
		
	}
	this.RemoveLayer = function () {
		for(var i=0; i<LayerObjects.length; i++) {
			lo = LayerObjects[i];
			lo.RemoveMe();
		}
	}
	this.HideLayer = function () {
		for(var i=0; i<LayerObjects.length; i++) {
			lo = LayerObjects[i];
			lo.HideMe();
		}
	}
	this.LayerParentId=null;
	this.Visible=false;
	this.CenterPoint = new DegreeAndPix();
	var ll = new VELatLong();
	var dm = new DdmMaps();
	ll = map.GetCenter();
	this.CenterPoint.Lat = ll.Latitude;
	this.CenterPoint.Long = ll.Longitude;
	var pix = map.LatLongToPixel(ll);
	this.CenterPoint.x = pix.x;
	this.CenterPoint.y = pix.y;
	this.nudge = 0;
	var layerid = null;
	layerid = 'Layer_' + MapLayerId;
	this.GetId = function(){
		if (layerid==null) {
			layerid = 'Layer_' + MapLayerId;
			MapLayerId++;
		}
		return layerid
	}
	this.SetId = function(idVal){
		layerid = idVal
	}
	this.AddContextMenu=false;
	var contextMenu = null;
	this.SetContextMenu = function(ContextObj){
		contextMenu = ContextObj;
		this.AddContextMenu = true;
	}
}

/**
 * High level vector graphic objects
 */
/**
 * @class MapObject is a class that represents
 * a shape object.  An array of MapObjects would
 * be considered a layer
 */
function PolyLayer()
{
	var polies = new Array();
	var dm = new DdmMaps();
	this.Add = function(poly){
		polies.push(poly);
	}
	/**
	 * Number of polies in the object
	 */
	this.PolyCount = function (){
		return polies.length;
	}
	/**
	 * Draw map object as a vml polyline
	 */
	this.DrawMe = function (){
		var p;
		for(var i=0; i<polies.length; i++) {
			p = polies[i]
			if (p.ParentId==null || p.length==0) {
				p.ParentId = this.ParentId
			} 
			p.DrawMe();
		}
	}
	this.HideMe = function(){
		for(var i=0; i<polies.length; i++) {
			var c = polies[i];
			c.HideMe();
		}
	}
	/**
	 * @param {int} xMove
	 * @param {int} yMove
	 * Move x and y by value in xMove and yMove
	 */
	this.MoveMe = function (xMove, yMove){
		var p;
		for(var i=0; i<polies.length; i++) {
			p = polies[i] 
			p.MoveMe(xMove, yMove);
		}
	}
	this.Recalc = function(){
		var p;
		var pl = polies.length;
		for(var i=0; i<pl; i++) {
			p = polies[i] 
			p.Recalc();
		}
	}
	this.RedrawMe = function (){
		
		var p;
		var pl = polies.length;
		for(var i=0; i<pl; i++)
		{
			p = polies[i];
			p.RedrawMe();
		} 
		
	}
	this.RemoveMe = function(){
		var p;
		for(var i=0; i<polies.length; i++) {
			p = polies[i] 
			p.RemoveMe();
		}
	}
	this.Title='';
	this.Me=null;
	this.StrokeColor = 'blue';
	this.StrokeWeight = '1px';
	this.ZIndex = '500';
	this.Position = 'absolute';
	this.Fill = true;
	this.FillColor = 'yellow';
	this.opacity = '.8';
	this.ParentId;
	var layerid = null;
	this.SetLayerId = function(inVal){
		layerid = inVal;
		var p = new PolyLine();
		for(var l=0; l<polies.length; l++) {
			p = polies[l];
			p.LayerId = inVal;
			polies.splice(l,1,p);
		}
	}
	this.GetLayerId = function(){
		return layerid;
	}
	this.Type = 'Poly';
	var id = null;
	this.GetId = function(){
		if (id==null) {
			id = 'PO_' + MapObjectId;
			MapObjectId++;
		} 
		return id;
	}
	this.SetId = function(val){
		id = val;
	}
	var contextMenu = null;
	this.SetContextMenu = function(ContextObj){
		contextMenu = ContextObj;
		this.AddContextMenu = true;
	}
}

function PathLayer(){
	var points = new Array();
	var segments = new Array();
	var ptBuffer = new Array();
	var subId = new Array();
	var dm = new DdmMaps();
	this.SubIdArray = function(){
		return subId;
	}
	this.AddPoint = function(objPoint){
		var pd = new DegreeAndPix();
		var pix = dm.Pixels(objPoint);
		pd.Lat = objPoint.Latitude;
		pd.Long = objPoint.Longitude;
		pd.x = pix.x;
		pd.y = pix.y;
		points.push(pd);
	}
	this.HideMe = function(){
		for(var i=0; i<points.length; i++) {
			var c = points[i];
			c.HideMe();
		}
		for(var j=0; j<segments.length; j++) {
			var s = segments[j];
			s.HideMe();
		}
	}
	this.RemoveMe = function(){
		for(var i=0; i<ptBuffer.length; i++) {
			var c = ptBuffer[i];
			c.RemoveMe();
		}
		for(var j=0; j<segments.length; j++) {
			var s = segments[j];
			s.RemoveMe();
		}
	}
	this.Recalc = function(){
		var pd = new DegreeAndPix();
		var pix;
		var ll = new objLatLong();
		for(var index=0; index<points.length; index++) {
			pd = points[index];
			ll.Lat = pd.Lat;
			ll.Long = pd.Long;
			pix = dm.Pixels(ll);
			pd.x = pix.x;
			pd.y = pix.y;
			points.splice(index,1, pd);
		}
		for(var i=0; i<ptBuffer.length; i++) {
			var c = ptBuffer[i];
			c.Recalc();
		}
		for(var j=0; j<segments.length; j++) {
			var s = segments[j];
			s.Recalc();
		}
	}
	this.RedrawMe = function(){
		var pix = new DegreeAndPix();
		for(var i=0; i<ptBuffer.length; i++) {
			var cir = ptBuffer[i];
			cir.DrawMe();
		} 
		for(var i=0; i<segments.length; i++) {
			var seg = segments[i];
			seg.DrawMe();
		}
	}
	this.DrawMe = function(){
		var pix = new DegreeAndPix();
		jslog.info('Drawing path layer');
		for(var c=0; c<points.length; c++) {
			var cir = new CircleObject();
			cir.SetDiameter(this.BufferRadius*2);
			cir.CenterPoint = points[c];
			cir.ParentId = this.ParentId;
			cir.LayerId = this.GetLayerId();
			ptBuffer.push(cir);
			//jslog.info(contextMenu);
			if (contextMenu!=null) {
				cir.SetContextMenu(contextMenu);
			} 
			cir.DrawMe();
		}
		for(i=0; i<points.length; i++){
			var ls = new LineSegment();
			var z=0;
			z = (i+1);
			pix = points[i];
			ls.from = pix;
			pix = points[z];
			ls.to = pix;
			ls.ParentId = this.ParentId;
			ls.LayerId = this.GetLayerId();
			segments.push(ls);
			if ((points.length - i)==2) {
				break;
			} 
		} 
		for(var i=0; i<segments.length; i++) {
			var seg = segments[i];
			if (contextMenu!=null) {
				seg.SetContextMenu(contextMenu);
			}
			seg.DrawMe();
			subId.push(seg.GetId());
		}
	}
	this.Me=null;
	this.StrokeColor = 'green';
	this.StrokeWeight = '4px';
	this.ZIndex = '600';
	this.Position = 'absolute';
	this.DrawBuffer = true;
	this.BufferFill = true;
	this.BufferFillColor = 'yellow';
	this.BufferRadius = '5';
	this.opacity = '.7';
	this.ParentId = '';
	this.Type = 'Path';
	var layerid = null;
	this.SetLayerId = function(inVal){
		layerid = inVal;
	}
	this.GetLayerId = function(){
		return layerid;
	}
	var contextMenu = null;
	this.SetContextMenu = function(ContextObj){
		contextMenu = ContextObj;
		this.AddContextMenu = true;
	}
}
function LocationLayer(){
	var points = new Array();
	var loc = new Array();
	var subId = new Array();
	var dm = new DdmMaps();
	this.SubIdArray = function(){
		return subId;
	}
	this.AddPoint = function(objPoint){
		var pd = new DegreeAndPix();
		var pix = dm.Pixels(objPoint);
		pd.Lat = objPoint.Latitude;
		pd.Long = objPoint.Longitude;
		pd.x = pix.x;
		pd.y = pix.y;
		points.push(pd);
	}
	this.HideMe = function(){
		for(var i=0; i<loc.length; i++) {
			var c = loc[i];
			c.HideMe();
		}
	}
	this.RemoveMe = function(){
		for(var i=0; i<loc.length; i++) {
			var c = loc[i];
			c.RemoveMe();
		}
	}
	this.Recalc = function(){
		var pd = new DegreeAndPix();
		var pix;
		for(var i=0; i<loc.length; i++) {
			var c = loc[i];
			pix = c.Recalc();
			pd = points[i];
			pd.x = pix.x;
			pd.y = pix.y;
			points.splice(i,1, pd);
		}
	}
	this.RedrawMe = function(){
		for(var i=0; i<loc.length; i++) {
			var cir = loc[i];
			
			cir.RedrawMe();
		} 
	}
	this.DrawMe = function(){
		var pix = new DegreeAndPix();
		var p = document.createElement("div");
		p.setAttribute("id", "testDiv");
		var l = points.length;
		for(var c=0; c<l; c++) {
			var cir = new Pin();
			cir.SetDiameter(this.BufferRadius*2);
			cir.CenterPoint = points[c];
			cir.ParentId = this.ParentId;
			cir.LayerId = this.GetLayerId();
			//cir.FillColor = this.BufferFillColor;
			//ptBuffer.push(cir);
			//jslog.info(contextMenu);
			//if (contextMenu!=null) {
			//	cir.SetContextMenu(contextMenu);
			//} 
			//jslog.info("Drawing circles");
			loc.push(cir);
			cir.Parent = p;
			cir.DrawMe();
		}
		var el = document.getElementById('myMap');
		el.appendChild(p);
	}
	this.MoveMe = function(xMove, yMove){
		for(var c=0; c<loc.length; c++) {
			var cir = new CircleObject();
			cir = loc[c];
			cir.MoveMe(xMove,yMove);
		}
	}
	this.Me=null;
	this.StrokeColor = 'green';
	this.StrokeWeight = '4px';
	this.ZIndex = '600';
	this.Position = 'absolute';
	this.DrawBuffer = true;
	this.BufferFill = true;
	this.BufferFillColor = 'blue';
	this.BufferRadius = '5';
	this.opacity = '.9';
	this.ParentId = '';
	this.Type = 'Path';
	var layerid = null;
	this.SetLayerId = function(inVal){
		layerid = inVal;
	}
	this.GetLayerId = function(){
		return layerid;
	}
	var contextMenu = null;
	this.SetContextMenu = function(ContextObj){
		contextMenu = ContextObj;
		this.AddContextMenu = true;
	}
}


function LocPoint(){
	this.FillColor = 'green';
	this.Width = '30px';
	this.Pt = new DegreeAndPix();
	this.Title = 'Location';
}

/**
 * Low level vector graphic objects
 */
function LineSegment() {
		var id = null;
		var dm = new DdmMaps();
		this.GetId = function(){
			if (id==null) {
				id = 'Line_' + MapObjectId;
				MapObjectId++;
			} 
			return id;
		}
		this.SetId = function(val){
			id = val;
		}
		this.RemoveMe = function(){
		var ele = document.getElementById(this.GetId());
		var par = document.getElementById(this.ParentId);
		if (ele != undefined) {
			jsutil.purge(ele);
			par.removeChild(ele);
		}
		}
		this.HideMe = function(){
			var el = document.getElementById(this.GetId());
			el.style.visibility = "hidden";
		}
		this.RedrawMe = function(){
			this.RemoveMe();
			this.Recalc();
			this.DrawMe();
		}
		this.Recalc = function(){
			var pd = new DegreeAndPix();
			var pix;
			var ll = new objLatLong();
			ll.Lat = this.from.Lat;
			ll.Long = this.from.Long;
			pix = dm.Pixels(ll);
			this.from.x = pix.x;
			this.from.y = pix.y;
			ll.Lat = this.to.Lat;
			ll.Long = this.to.Long;
			pix = dm.Pixels(ll);
			this.to.x = pix.x;
			this.to.y = pix.y;
		}
		this.DrawMe = function(){
			if(this.to.x < map.GetLeft() || this.to.y < map.GetTop() || this.from.x < map.GetLeft()||this.from.y<map.GetTop()){
				
			}else{
				var t = this.to;
				var f = this.from;
				var poly = document.createElement("v:line");
				poly.setAttribute("id", this.GetId());
				poly.setAttribute('to', t.x + " " + t.y);
				poly.setAttribute('from', f.x + " " + f.y);
				poly.setAttribute("stroke", "true");
				poly.setAttribute("strokecolor", this.StrokeColor);
				poly.setAttribute("strokeweight", this.StrokeWeight);
				poly.setAttribute("opacity", this.opacity);
				var Parent = document.getElementById(this.ParentId);
				Parent.appendChild(poly);
				var pol = document.getElementById(this.GetId());
				this.Me = pol.appendChild(poly);
				pol.style.zIndex = this.ZIndex;
				pol.style.position = this.Position;		
				if (contextMenu != null) {
					this.AttachContext();
				}
			} 
		}
		this.from = null;
		this.to = null;
		this.StrokeColor = 'blue';
		this.StrokeWeight = '1px';
		this.ZIndex = '600';
		this.Position = 'absolute';
		this.Buffer1 = null;
		this.Buffer2 = null;
		this.ParentId = '';
		this.LayerId = null;
		var contextMenu = null;
		this.SetContextMenu = function(ContextObj){
			contextMenu = ContextObj;
			this.AddContextMenu = true;
		}
		this.AttachContext = function(){
			contextMenu.SetTrigger(this.GetId());
		}
	}
	
function CircleObject(){
	var dm = new DdmMaps();
	this.HideMe = function(){
		var el = document.getElementById(this.GetId());
		el.style.visibility = "hidden";
	}
	this.DeleteMe = function(){
		var ele = document.getElementById(this.GetId());
		var par = document.getElementById(this.ParentId);
		par.removeChild(ele);
		delete MapObjectIndex.ObjectId[this.GetId()];
	}
	this.RemoveMe = function(){
		var ele = document.getElementById(this.GetId());
		var par = document.getElementById(this.ParentId);
		if (ele != undefined) {
			jsutil.purge(ele);
			par.removeChild(ele);
		} 
	}
	this.RedrawMe = function (){
		this.Left = this.CenterPoint.x - (diam/2);
		this.Top = this.CenterPoint.y - (diam/2);		
		this.Me.style.left = this.Left;
		this.Me.style.top = this.Top;
		this.Me.style.width = diam;
		this.Me.style.height = diam;
		var Parent = document.getElementById(this.ParentId);
		Parent.appendChild(this.Me);
	}
	this.Recalc = function(){
		var pd = new DegreeAndPix();
		var pix ;
		var ll = new objLatLong();
			ll.Lat = this.CenterPoint.Lat;
			ll.Long = this.CenterPoint.Long;
			pix = dm.Pixels(ll);
			this.CenterPoint.x = pix.x;
			this.CenterPoint.y = pix.y;
			this.RecalcDiameter();
		return pix;
	}
	this.DrawMe = function(){
		
		if (this.CenterPoint.x==null) {
			var ll = new objLatLong();
			ll.Lat = this.CenterPoint.Lat;
			ll.Long = this.CenterPoint.Long;
			var pix;
			pix = dm.Pixels(ll);
			this.CenterPoint.x = pix.x;
			this.CenterPoint.y = pix.y;
			//jslog.info(pix.x + ' : ' + pix.y);
		}
		this.Title = "Latitude: " + this.CenterPoint.Lat + " Longitude: " + this.CenterPoint.Long;
		//jslog.info(contextMenu);
			if (contextMenu != null) {
				this.AttachContext();
			} 
		this.Left = this.CenterPoint.x - (diam/2);
		this.Top = this.CenterPoint.y - (diam/2);
		MapObjectIndex.ObjectId[this.GetId()] = this;
		//jslog.info(this.GetId());
		//jslog.info(MapObjectIndex.ObjectId[this.GetId()]);
		
		var poly = document.createElement("v:oval");
		poly.setAttribute("id", this.GetId());
		poly.setAttribute("stroked", this.Stroke);
		poly.setAttribute("strokecolor", this.StrokeColor);
		poly.setAttribute("strokeweight", this.StrokeWeight);
		poly.setAttribute("opacity", this.opacity);
		poly.setAttribute("fill", this.Fill);
		poly.setAttribute("fillcolor", this.FillColor);
		poly.setAttribute("title", this.Title);
    	poly.style.left = this.Left;
		poly.style.top = this.Top;
		poly.style.zIndex = this.ZIndex;
		poly.style.position = this.Position;			
		poly.style.width = diam;
		poly.style.height = diam;
    	//poly.attachEvent("oncontextmenu", test)
		var Parent = document.getElementById(this.ParentId);
		this.Me = Parent.appendChild(poly);
		//var pol = document.getElementById(this.GetId());
		//pol.appendChild(poly);
		//this.Me = pol.appendChild(poly);
		//this.ToolTipText(this.Title);
		//RenderTooltip(this.GetId());
	}
	this.MoveMe = function (xMove, yMove){
		var p = "";
		var pixel;
		var pd = new DegreeAndPix();
		var ll = new VELatLong();
		this.CenterPoint.x -=xMove;
		this.CenterPoint.y -= yMove;
		this.Left = this.CenterPoint.x - (diam/2);
		this.Top = this.CenterPoint.y - (diam/2);		
		this.Me.style.left = this.Left;
		this.Me.style.top = this.Top;
	}
	this.Left = '';
	this.Top = '';
	this.CenterPoint = new DegreeAndPix();
	this.Fill = true;
	this.FillColor = 'yellow';
	this.Me=null;
	this.StrokeColor = 'green';
	this.StrokeWeight = '1px';
	this.Stroke = false;
	this.ZIndex = '400';
	this.Position = 'absolute';
	this.opacity = '.7';
	this.ParentId = '';
	this.Type = 'Circle';
	this.Title = '';
	var tooltip = null;
	var tooltipcontent = '';
	this.ToolTipText = function(textVal){
		tooltipcontent = textVal;
	}
	function RenderTooltip(id){
		var thisid;
		thisid = 'Tooltip_' + ToolTipId;
		ToolTipId++;
		tooltip = new YAHOO.widget.Tooltip(thisid, { context:id, text:tooltipcontent } );		
	}
	var diam = 0;
	this.SetDiameter = function(valInMiles){
		diam = dm.ConvertMilesToPix(valInMiles);
	}
	this.GetDiameterInPix = diam;
	this.RecalcDiameter = function(){
		diam = dm.ConvertMilesToPix(this.GetDiameterInMiles());
	}
	this.GetDiameterInMiles = function(){
		return diam * dm.MilesPerPix();
	}
	var id = null;
	this.GetId = function(){
		if (id==null) {
			id = 'Circle_' + MapObjectId;
			MapObjectId++;
		} 
		return id;
	}
	this.SetId = function(val){
		id = val;
	}
	this.AttachContext = function(){
		contextMenu.SetTrigger(this.GetId());
	}
	var contextMenu = null;
	this.SetContextMenu = function(ContextObj){
		contextMenu = ContextObj;
	}
	this.ZoomMe = true;
	this.LayerId = null;
}

function PolyLine(){
	var points = new Array();
	var dm = new DdmMaps();
	/**
	 * @param {VELatLong} lat long object input
	 * Adds a point to the map object
	 */
	this.AddPoint = function (objPoint){
		var pd = new DegreeAndPix();
		var pix = dm.Pixels(objPoint);
		pd.Lat = objPoint.Latitude;
		pd.Long = objPoint.Longitude;
		pd.x = pix.x;
		pd.y = pix.y;
		points.push(pd);
	}		
	/**
	 * @param {int}
	 * Removes point at the specified index
	 */
	this.RemovePoint = function (Index){
		points.splice(Index);
	}
	/**
	 * Number of points in the object
	 */
	this.PointLength = function (){
		return points.length;
	}
	this.HideMe = function(){
		this.Visible = false;
		this.Me.visibility = "hidden";
		//var el = document.getElementById(this.GetId());
		//var el = this.Parent.getElementById(this.GetId());
		//el.style.visibility = "hidden";
		//this.RemoveMe();
	}
	/**
	 * Remove map object html element from document
	 */
	this.RemoveMe = function (){
		//jslog.info("Removing: " + this.GetId());
		var ele = document.getElementById(this.GetId());
		var par = document.getElementById(this.ParentId);
		if(ele != undefined){
			jsutil.purge(ele);
			par.removeChild(ele);
		}
	}
	/**
	 * Draw map object as a vml polyline
	 */
	this.DrawMe = function (){
		var poly = document.createElement("v:polyline");
		var Parent = document.getElementById(this.ParentId);
		var pix = new DegreeAndPix();
		var p = "";
		for(i=0; i<points.length; i++)
		{
			pix = points[i];
			p = p + pix.x + " " + pix.y + " ";
		} 
		poly.setAttribute("Points", p);
		poly.setAttribute("id", this.GetId());
		poly.setAttribute("stroke", "true");
		poly.setAttribute("strokecolor", this.StrokeColor);
		poly.setAttribute("strokeweight", this.StrokeWeight);
		poly.setAttribute("fill", this.Fill);
		poly.setAttribute("fillcolor", this.FillColor);
		poly.setAttribute("opacity", this.opacity);
		poly.setAttribute("title", this.Title);
		poly.style.zIndex = this.ZIndex;
		poly.style.position = this.Position;
		this.Me = Parent.appendChild(poly);
		if (contextMenu != null) {
				this.AttachContext();
			} 
	}
	/**
	 * @param {int} xMove
	 * @param {int} yMove
	 * Move x and y by value in xMove and yMove
	 */
	this.MoveMe = function (xMove, yMove){
		var p = "";
		var pixel;
		var pd = new DegreeAndPix();
		var Buffer = new Array();
		var ll = new VELatLong();
		for(i=0; i<points.length; i++)
		{
			pd = points[i];
			ll.Latitude = pd.Lat;
			ll.Longitude = pd.Long;
			Buffer[i] = (pd.x-=xMove) + " " + (pd.y-=yMove) + " ";
		}
		this.Me.points.value = Buffer.join("");	
	}
	this.RedrawMe = function(){
		var p = "";

		var pd = new DegreeAndPix();
		var Buffer = new Array();
		for(i=0; i<points.length; i++)
		{
			pd = points[i];
			Buffer[i] = pd.x + " " + pd.y + " ";
		}
		this.Me.points.value = Buffer.join("");	
		this.Me.visibility = "visible";
	}
	this.Recalc = function(){
		var pd = new DegreeAndPix();
		var pix ;
		var ll = new objLatLong();
		
		for(var i=0; i<points.length; i++) {
			pd = points[i];
			ll.Lat = pd.Lat;
			ll.Long = pd.Long;
			pix = dm.Pixels(ll);
			pd.x = pix.x;
			pd.y = pix.y;
			points.splice(i,1, pd);
		}
	}
	this.Title='';
	this.Me=null;
	this.StrokeColor = 'blue';
	this.StrokeWeight = '1px';
	this.ZIndex = '500';
	this.Position = 'absolute';
	this.Fill = true;
	this.FillColor = 'yellow';
	this.opacity = '.8';
	this.ParentId;
	this.Parent = null;
	this.LayerId = null;
	this.Type = 'Poly';
	var id = null;
	this.GetId = function(){
		if (id==null) {
			id = 'PO_' + MapObjectId;
			MapObjectId++;
		} 
		return id;
	}
	this.SetId = function(val){
		id = val;
	}
	var contextMenu = null;
	this.SetContextMenu = function(ContextObj){
		contextMenu = ContextObj;
		this.AddContextMenu = true;
	}
	this.AttachContext = function(){
		contextMenu.SetTrigger(lo.GetId());
	}
}

function Pin(){
	
	var dm = new DdmMaps();
	this.HideMe = function(){
		this.Visible = false;
		var el = document.getElementById(this.GetId());
		//var el = this.Parent.getElementById(this.GetId());
		el.style.visibility = "hidden";
	}
	this.DeleteMe = function(){
		var ele = document.getElementById(this.GetId());
		var par = document.getElementById(this.ParentId);
		par.removeChild(ele);
		delete MapObjectIndex.ObjectId[this.GetId()];
	}
	this.RemoveMe = function(){
		var ele = document.getElementById(this.GetId());
		var par = document.getElementById(this.ParentId);
		if (ele != undefined) {
			jsutil.purge(ele);
			par.removeChild(ele);
		} 
	}
	this.RedrawMe = function (){
		this.Left = (this.CenterPoint.x -5) + 'px'; 	//- (diam/2);
		this.Top = (this.CenterPoint.y -5) + 'px';	// (diam/2);
		
		this.Me.style.left = this.Left;
		this.Me.style.top = this.Top;
		this.Me.style.width = '10px';
		this.Me.style.height = '10px';
		this.Me.style.visibility = "visible";
		this.Visible = true;
		
		var el = document.getElementById(this.GetId());
		el.style.visibility = "visible";
		el.style.left = this.Left;
		el.style.top = this.Top;
		el.style.width = diam;
		el.style.height = diam;
		
		MapObjectIndex.ObjectId[this.GetId()] = this;
	}
	this.Recalc = function(){
		var pd = new DegreeAndPix();
		var pix ;
		var ll = new objLatLong();
			ll.Lat = this.CenterPoint.Lat;
			ll.Long = this.CenterPoint.Long;
			pix = dm.Pixels(ll);
			this.CenterPoint.x = pix.x;
			this.CenterPoint.y = pix.y;
			this.RecalcDiameter();
		return pix;
	}
	this.DrawMe = function(){
		
		if (this.CenterPoint.x==null) {
			var ll = new objLatLong();
			ll.Lat = this.CenterPoint.Lat;
			ll.Long = this.CenterPoint.Long;
			var pix;
			pix = dm.Pixels(ll);
			this.CenterPoint.x = pix.x;
			this.CenterPoint.y = pix.y;
			//jslog.info(pix.x + ' : ' + pix.y);
		}
		this.Visible = true;
		this.Title = "Latitude: " + this.CenterPoint.Lat + " Longitude: " + this.CenterPoint.Long;
		//jslog.info(contextMenu);
			//if (contextMenu != null) {
			//	this.AttachContext();
			//} 
		this.Left = (this.CenterPoint.x -5) + 'px'; 	//- (diam/2);
		this.Top = (this.CenterPoint.y -5) + 'px';	// (diam/2);
		MapObjectIndex.ObjectId[this.GetId()] = this;
		//jslog.info(this.GetId());
		//jslog.info(MapObjectIndex.ObjectId[this.GetId()]);
		
		var el = document.createElement("div");
		el.setAttribute("id", this.GetId());
		el.setAttribute("title", this.Title);
		el.style.backgroundImage = "url(images/dotblue_sm.gif)";
		el.style.backgroundPosition = "center center";
		el.style.backgroundRepeat = "no-repeat";
		el.style.backgroundColor = "transparent";
		el.style.zIndex = this.ZIndex;
		el.style.position = this.Position;
		el.style.left = this.Left;
		el.style.top = this.Top;
		el.style.width = this.Width;
		el.style.height = this.Height;
    	
		//var Parent = document.getElementById(this.ParentId);
		var Parent = this.Parent;
		this.Me = Parent.appendChild(el);
		
	}
	this.MoveMe = function (xMove, yMove){
		var p = "";
		var pixel;
		var pd = new DegreeAndPix();
		var ll = new VELatLong();
		this.CenterPoint.x -=xMove;
		this.CenterPoint.y -= yMove;
		this.Left = this.CenterPoint.x - (diam/2);
		this.Top = this.CenterPoint.y - (diam/2);		
		this.Me.style.left = this.Left;
		this.Me.style.top = this.Top;
	}
	this.Left = '';
	this.Top = '';
	this.Width = '10px';
	this.Height = '10px';
	this.CenterPoint = new DegreeAndPix();
	this.Me=null;
	this.ZIndex = '400';
	this.Position = 'absolute';
	this.opacity = '.7';
	this.ParentId = '';
	this.Parent = null;
	this.Type = 'Pin';
	this.Title = '';
	this.Visible = false;
	var tooltip = null;
	var tooltipcontent = '';
	this.ToolTipText = function(textVal){
		tooltipcontent = textVal;
	}
	function RenderTooltip(id){
		var thisid;
		thisid = 'Tooltip_' + ToolTipId;
		ToolTipId++;
		tooltip = new YAHOO.widget.Tooltip(thisid, { context:id, text:tooltipcontent } );		
	}
	var diam = 0;
	this.SetDiameter = function(valInMiles){
		diam = dm.ConvertMilesToPix(valInMiles);
	}
	this.GetDiameterInPix = diam;
	this.RecalcDiameter = function(){
		diam = dm.ConvertMilesToPix(this.GetDiameterInMiles());
	}
	this.GetDiameterInMiles = function(){
		return diam * dm.MilesPerPix();
	}
	var id = null;
	this.GetId = function(){
		if (id==null) {
			id = 'Circle_' + MapObjectId;
			MapObjectId++;
		} 
		return id;
	}
	this.SetId = function(val){
		id = val;
	}
	this.AttachContext = function(){
		contextMenu.SetTrigger(this.GetId());
	}
	var contextMenu = null;
	this.SetContextMenu = function(ContextObj){
		contextMenu = ContextObj;
	}
	this.ZoomMe = true;
	this.LayerId = null;
}